assume cs:codesg,ds:data,ss:stack
data segment
	db 16 dup(20h),0
	db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984'
	db '1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,19514,345980,590827,853530
	dd 1186000,1943000,2759000,3753000,4619000,5937000
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226,11524,14430,15257,17800
data ends
table segment
	db 21 dup('year summ ne ?? ')
table ends
stack segment
	dw 32 dup(0)
stack ends

codesg segment
start:	mov ax,data
	mov ds,ax
	mov ax,table
	mov es,ax
	mov ax,stack
	mov ss,ax
	mov sp,40h
	mov si,10h
	mov cx,0
	mov di,0
	
	call fill_table

	call show_table

	mov ax,4c00h
	int 21h
	
	;ds:si the pointer of the string
clear_str:
	push cx
	push si
	push ax

	mov cx,0fh
	mov al,20h
	mov ah,0
set_20h:
	
	mov [si],al
	inc si
	loop set_20h
	mov [si],ah

	pop ax
	pop si
	pop cx
	ret

	;dh the row to be clearest
clear_row:
	push cx
	push es
	push si
	add cx,0b800h
	mov es,cx
	mov si,0
	mov cx,50h
set_20:
	mov ch,20h
	mov es:[si],ch
	add si,2
	mov ch,0
	loop set_20
	pop si
	pop es
	pop cx
	ret
	
	;es:di the start pointer of table
show_table:
	push di
	push si
	push cx
	push ax
	push dx
	push bx
	mov si,0
	mov cx,21
	mov dx,510h
	
show_row:
	call clear_row
	push cx
	push dx
	mov cx,2
	call clear_str
	mov ax,es:[di]
	mov [si],ax
	mov ax,es:[di+2]
	mov [si+2],ax
	call show_str

	call clear_str
	mov ax,es:[di+5]
	mov dx,es:[di+7]
	call dtoc
	mov al,20h
	mov [bx],al
	pop dx
	push dx
	add dl,10h
	call show_str

	call clear_str
	mov dx,0
	mov ax,es:[di+0ah]
	call dtoc 
	mov al,20h
	mov [bx],al
	pop dx
	push dx
	add dl,20h
	call show_str

	call clear_str
	mov dx,0
	mov ax,es:[di+0dh]
	call dtoc 
	mov al,20h
	mov [bx],al
	pop dx
	push dx
	add dl,30h
	call show_str
	pop dx
	add di,10h
	inc dh
	pop cx
	loop show_row
	pop bx
	pop dx
	pop ax
	pop cx
	pop si
	pop di
	ret

	;fill the table with data
	;ds:si the pointer of the data
	;es:di the pointer of the table
fill_table:
	push si
	push di
	push ax
	push dx
	push cx
	push bx
	mov bx,0
	mov cx,15h
get_word:
	push cx
	mov ax,[si+bx]
	mov es:[di],ax
	mov ax,[si+bx].2
	mov es:[di+2],ax
	
	mov ax,[si+0a8h]
	mov es:[di+0ah],ax

	mov al,20h
	mov es:[di+4],al
	mov es:[di+8],al
	mov es:[di+0fh],al
	mov es:[di+0ch],al

	mov dx,[si+bx+54h].2
	mov es:[di+7],dx
	mov ax,[si+bx+54h]
	mov es:[di+5],ax
	mov cx,es:[di+0ah]
	call divdw
	mov es:[di+0dh],ax
	add di,10h
	add si,2
	add bx,2
	pop cx
	loop get_word

	pop bx
	pop cx
	pop dx
	pop ax
	pop di
	pop si
	ret

	;convert the word type data to decimal string end with 0  
	;ax the word type data
	;ds:si the start pointer of the string
	;ret de:bx the end pointer of string
dtoc:
	push ax
	push cx
	push dx
	push si
div10:	
	mov cx,0ah
	call divdw
	add cx,30h
	mov [si],cl
	inc si
	mov cx,dx
	jcxz d2
	jmp div10
d2:	mov cx,ax
	jcxz end_div10
	jmp div10
end_div10:	
	mov byte ptr [si],0
	mov cx,si
	mov bx,si
	inc bx
	pop si
	call reverse_str
	pop dx
	pop cx
	pop ax
	ret

	;reverse the decimal string
	;ds:si the pointer of string
	;cx the length of string
reverse_str:
	push si
	push di
	push ax
	push cx
	mov di,cx
	dec di
	mov ax,cx
	jcxz end_rev
	dec cx
	jcxz end_rev
	mov cx,2
	div cl
	mov cl,al
exchange:
	mov al,[si]
	mov ah,[di]
	mov [si],ah
	mov [di],al
	inc si
	dec di
	loop exchange
end_rev:
	pop cx
	pop ax
	pop di
	pop si
	ret

	
	;Show the string end with '0' on screen at the specific row and coloum  in specific color 
	;dh: row num which between 0 and 24
	;dl: coloum num which between 0 and 79
	;cl: font and background color
	;ds:si the pointer of string to be showed
show_str:
	push es
	push bp
	push si
	push dx
	push cx

	;set the row num
	mov al,0ah
	mul dh
	add ax,0b800h
	mov es,ax
	;set the coloum num
	mov al,2
	mul dl
	mov bp,ax
	mov dl,cl
	mov ch,0
to_buffer:
	mov cl,ds:[si]
	jcxz end_show_str
	mov es:[bp],cl
	mov es:[bp].1,dl
	add bp,2
	inc si
	jmp to_buffer
end_show_str:
	pop cx
	pop dx
	pop si
	pop bp
	pop es
	ret

	;divide the word with no divide overflow
	;dx: the high position of divisor
	;ax: the low position of divisior
	;cx: the num to be divided
	;ret dx:the high position of result
	;ret ax:the low position of result
	;ret cx:the remainder
divdw:
	push bp
	sub sp,4
	mov bp,sp
	
	mov [bp],ax
	mov ax,dx
	mov dx,0
	div cx
	mov [bp].2,ax
	mov ax,[bp]
	div cx
	mov cx,dx
	mov dx,[bp].2
	add sp,4
	pop bp
	ret

codesg ends
end start